/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.dtgenerator.core.rtgen.lcpgenerator;

import com.inspur.edp.bef.bizentity.GspBizEntityObject;
import com.inspur.edp.bef.bizentity.operation.BizAction;
import com.inspur.edp.bef.bizentity.operation.BizMgrAction;
import com.inspur.edp.bef.bizentity.operation.BizOperation;
import com.inspur.edp.bef.bizentity.operation.internalmgraction.IInternalMgrAction;
import com.inspur.edp.bef.core.lcp.StandardLcp;
import com.inspur.edp.bef.dtgenerator.api.BefApiGeneratorContext;
import com.inspur.edp.bef.dtgenerator.core.BefCoreGenCtx;
import com.inspur.edp.bef.dtgenerator.core.rtgen.lcpgenerator.method.LcpAddExtendsGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.lcpgenerator.method.LcpBeInfoGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.lcpgenerator.method.LcpCreateMgrGeneratorcs;
import com.inspur.edp.bef.dtgenerator.core.rtgen.lcpgenerator.method.LcpDefaultConstructorGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.lcpgenerator.method.LcpDefaultNoParaConstructorGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.lcpgenerator.method.LcpTransDeleteChildGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.lcpgenerator.method.LcpTransGenerator;
import com.inspur.edp.bef.dtgenerator.core.rtgen.lcpgenerator.method.LcpTransRetrieveDefaultChildGenerator;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.item.ClassGenerator;
import com.inspur.edp.caf.generator.item.ClassGeneratorContext;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.caf.generator.property.ClassPropertyGenerator;
import com.inspur.edp.cef.entity.config.CefConfig;
import com.inspur.edp.cef.gencommon.MediateType;
import com.inspur.edp.cef.generator.coreGenerator.base.CefCoreGeneratorContext;
import com.inspur.edp.cef.generator.coreGenerator.base.mgrGenerator.ManagerGeneratorContext;
import com.inspur.edp.cef.generator.overall.GeneratorUtil;
import java.util.ArrayList;
import java.util.Arrays;

import com.inspur.edp.cef.spi.jsonser.entity.AbstractEntitySerializerItem;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import org.eclipse.jdt.core.dom.Modifier;

public class LcpClassGenerator extends ClassGenerator {
  //#region 字段和属性

  private BefCoreGenCtx projContext;
  private String generatedMgrType;

  public LcpClassGeneratorContext getLcpClassGenContext() {
    return (LcpClassGeneratorContext) super.getContext();
  }

  public static LcpClassGenerator Create(BefCoreGenCtx projContext, String generatedMgrType) {
    return new LcpClassGenerator(projContext, generatedMgrType);
  }

  private LcpClassGenerator(BefCoreGenCtx projContext, String generatedMgrType) {
    super(projContext.getCompilationUnitInfo());
    this.projContext = projContext;
    this.generatedMgrType = generatedMgrType;
  }


  @Override
  protected ClassGeneratorContext createClassInfoContext() {
    return LcpClassGeneratorContext.Create(projContext);
  }

  @Override
  protected TypeInfo setParentClass() {
    return new TypeInfo(StandardLcp.class);
  }

  @Override
  protected ArrayList<TypeInfo> addParentInterfaces() {
    BefApiGeneratorContext apiGeneratorContext = (BefApiGeneratorContext) projContext.getBeGenCtx()
        .getApiGenContext();
    TypeInfo typeInfo = new TypeInfo(apiGeneratorContext.getMgrAllInterfaceType().getFullName());
    typeInfo.setUseFullName(true);
    return new ArrayList<TypeInfo>(Arrays.asList(new TypeInfo[]{typeInfo}));
  }

  public static MediateType GetLcpType(CefConfig config) {
    return new MediateType(config.getDefaultNamespace(), GeneratorUtil.getName(config.getID()));
  }

  protected String getNameSpace() {
    return GetLcpType(getLcpClassGenContext().getProjContext().getConfig()).getNamespace();
  }

  @Override
  protected String getName() {
    return GetLcpType(getLcpClassGenContext().getProjContext().getConfig()).getClassName();
  }

  @Override
  protected ArrayList<Modifier.ModifierKeyword> getAccessModifier() {
    return new java.util.ArrayList<Modifier.ModifierKeyword>(java.util.Arrays
        .asList(new Modifier.ModifierKeyword[]{Modifier.ModifierKeyword.PUBLIC_KEYWORD}));
  }

  protected String buildTransMethodName() {
    return "GetBEManager";
  }


  @Override
  protected java.util.ArrayList<ClassMethodGenerator> createMethodGenerators() {
    java.util.ArrayList<ClassMethodGenerator> gens = getTransMethods();
    LcpCreateMgrGeneratorcs createGenerator = LcpCreateMgrGeneratorcs.Create(generatedMgrType);
    gens.add(createGenerator);
    gens.add(LcpBeInfoGenerator.Create(getLcpClassGenContext()));
    if (getLcpClassGenContext().getProjContext().getBeGenCtx().getMetadata().getHeader().isExtendable()) {
      gens.add(new LcpAddExtendsGenerator(getLcpClassGenContext()));
    }
    return gens;
  }

  @Override
  protected java.util.ArrayList<ClassPropertyGenerator> createPropertyGenerators() {
    return new java.util.ArrayList<ClassPropertyGenerator>(
        java.util.Arrays.asList(new ClassPropertyGenerator[]{}));
  }
  //#endregion

  //#region

  @Override
  protected void afterGenerate() {
    super.afterGenerate();
    getLcpClassGenContext().getProjContext()
        .setLcpTypeInfo(new MediateType(getName(), getNameSpace()));
  }
  //#endregion

  private java.util.ArrayList<ClassMethodGenerator> getTransMethods() {
    return getTransMethods(projContext.getMgrImplType());
  }

  private java.util.ArrayList<ClassMethodGenerator> getTransMethods(MediateType transType) {
    java.util.ArrayList<ClassMethodGenerator> gens = new java.util.ArrayList<ClassMethodGenerator>();
    for (BizOperation operation : projContext.getBE().getBizMgrActions()) {
      if (operation instanceof IInternalMgrAction) {
        continue;
      }
      gens.add(new LcpTransGenerator(transType, (BizMgrAction) operation, projContext));
    }

    for (GspBizEntityObject node : projContext.getBE().getAllNodes()) {
      if (node.getIsRootNode()) {
        continue;
      }
      gens.add(new LcpTransDeleteChildGenerator(node));
      gens.add(new LcpTransRetrieveDefaultChildGenerator(node));
    }

    return gens;
  }
}
